inner = 'window';

function say() {
  console.log(inner);
  console.log(this.inner);
}

var obj1 = (function () {
  var inner = '1-1';
  return {
    inner: '1-2',
    say: function () {
      console.log(inner);
      console.log(this.inner);
    }
  }
})();

var obj2 = (function () {
  var inner = '2-1';
  return {
    inner: '2-2',
    say: function () {
      console.log(inner);
      console.log(this.inner);
    }
  }
})();

var obj3 = (function () {
  var inner = '3-1';
  return {
    inner: '3-2',
    say: () => {
      console.log(inner);
      console.log(this.inner);
    }
  }
})()
say();
// window
// window
obj1.say();
// 1-1
// 1-2
obj2.say();
// 2-1
// 2-2
obj3.say();
// 3-1
// window
obj1.say = say;
obj1.say();
// window
// 1-2
obj1.say = obj2.say;
obj1.say();
// 2-1
// 1-2

/**
 * this
 */
var a = 10;
var o = {
  a: 11,
  b: {
    a: 12,
    fn: () => {
      console.log(this, this.a);
    }
  }
}
o.b.fn(); // window, 10

var name = 'window';
var A = {
  name: 'A',
  sayHello: function () {
    var s = () => console.log(this.name)
    return s; // 返回箭头函数s
  }
}

var sayHello = A.sayHello();
sayHello(); // 输出A 

var B = {
  name: 'B',
}

sayHello.call(B); // 还是A
sayHello.call(); // 还是A

var a = 0;
var obj = {
  a: 1,
  func: function () {
    console.log(this.a, '===='); // 1
    const foo = function () {
      console.log(this.a, '****'); // 0
    }
    foo();
  }
};
obj.func();

// 1 '===='
// 0 '****'

/**
 * 词法作用域
 */
const a = 1;
function foo() {
  const a = 2
  return function () {
    console.log(a)
  }
}
function bar() {
  const a = 3
  const func = foo()
  return func
}
const run = bar()
run() // 2